﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PopupControl;
//using _180FrameWork.Common;
//using _180FrameWork.Common.Models;
using System.Dynamic;
using System.Drawing;

namespace _180FrameWork.CustControls
{
    public partial class CustFuzzyQueryBox : TextBox
    {
        //解决输入法BUG   
        //[DllImport("imm32.dll")]
        //private static extern IntPtr ImmGetContext(IntPtr hwnd);
        //[DllImport("imm32.dll")]
        //private static extern bool ImmGetConversionStatus(IntPtr himc, ref int lpdw, ref int lpdw2);
        //[DllImport("imm32.dll")]
        //private static extern bool ImmGetOpenStatus(IntPtr himc);

        //[DllImport("imm32.dll")]
        //private static extern int ImmSimulateHotKey(IntPtr hwnd, int dw);


        /// <summary>
        /// 弹出框
        /// </summary>
        private Popup popup;
        /// <summary>
        /// 弹出框内容
        /// </summary>
        private CustFuzzyQueryList list;
        /// <summary>
        /// 右侧弹出框
        /// </summary>
        private Button btnPop;

        /// <summary>
        /// 选中事件
        /// </summary>
        [Category("Data")]
        [Description("CustFuzzyQueryBox_ItemSelectedDescr")]
        //public event EventHandler ItemSelected;
        public event AfterSelectorEventHandler AfterSelector;

        /// <summary>
        /// 查询字符串变更事件
        /// </summary>
        [Category("Data")]
        [Description("CustFuzzyQueryBox_QueryStringChangedDescr")]
        public event QueryStringChangeEventHandler QueryStringChangeEvent;

        ///// <summary>
        ///// 查询id
        ///// </summary>
        //[DefaultValue("123")]
        //public string QueryId { get { return this._QueryId; } set { this._QueryId = value; } }
        //private string _QueryId = "123";

        public int PopupHeight
        {
            get { return this.popup.Height; }
            set { this.popup.Height = value; }
        }

        public int PopupWidth
        {
            get { return this.popup.Width; }
            set { this.popup.Width = value; }
        }

        private System.Timers.Timer DelayTimer;

        private object _SelectedItem = null;
        /// <summary>
        /// 选中数据
        /// </summary>
        public object SelectedItem
        {
            get
            {
                return this._SelectedItem;
            }
            set
            {
                try
                {
                    this.TextChanged -= new EventHandler(CustFuzzyQueryBox_TextChanged);
                    //IsBuzy = true;
                    if (this.DisplayMember != "" && value != null)
                    {
                        this.Text = GetObjPropValue(value, this.DisplayMember);
                        //this.Text = list.GetSelectedItemText(this.DisplayMember);
                        this.Select(this.Text.Length, 0);
                    }
                    //IsBuzy = false;
                    this.TextChanged += new EventHandler(CustFuzzyQueryBox_TextChanged);

                    if (this.ValueMember != "" && value != null)
                    {
                        this.Value = GetObjPropValue(value, this.ValueMember);
                        //this.Value = list.GetSelectedItemText(this.ValueMember);
                    }
                }
                catch { }
                this._SelectedItem = value;
                //if (this.ItemSelected != null)
                //{
                //    this.ItemSelected(this, new EventArgs());
                //}
                RaiseAfterSelector(this, new AfterSelectorEventArgs(-1, -1, value));
                popup.Close();
            }
        }
        private string GetObjPropValue(object obj, string prop)
        {
            string value = "";
            foreach (var p in obj.GetType().GetProperties())
            {
                if (p.Name == prop)
                {
                    value = p.GetValue(obj, null).ToString();
                    break;
                }
            }
            return value;
        }
        protected void OnAfterSelector(object sender, AfterSelectorEventArgs e)
        {
            if (AfterSelector != null)
            {
                AfterSelector(sender, e);
            }
        }

        protected virtual void RaiseAfterSelector(object sender, AfterSelectorEventArgs e)
        {
            OnAfterSelector(sender, e);
        }
        private object _Value = null;
        public object Value
        {
            get { return this._Value; }
            set { this._Value = value; }
        }

        private string _ValueMember = "";
        /// <summary>
        /// 值属性
        /// </summary>
        public string ValueMember
        {
            get { return this._ValueMember; }
            set { this._ValueMember = value; }
        }

        private string _DisplayMember = "";
        /// <summary>
        /// 显示属性
        /// </summary>
        public string DisplayMember
        {
            get { return this._DisplayMember; }
            set { this._DisplayMember = value; }
        }

        public CustFuzzyQueryBox()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            list = new CustFuzzyQueryList();
            popup = new Popup(list);
            popup.FocusOnOpen = false;
            popup.AutoClose = false;
            list.ItemSelected += new EventHandler(list_ItemSelected);

            DelayTimer = new System.Timers.Timer();
            DelayTimer.Interval = 300;
            DelayTimer.Elapsed += new System.Timers.ElapsedEventHandler(DelayTimer_Elapsed);

            btnPop = new Button();
            btnPop.Dock = DockStyle.Right;
            btnPop.Location = new Point(0, 0);
            btnPop.Name = "btnPop";
            btnPop.Size = new Size(23, 23);
            btnPop.TabIndex = 0;
            btnPop.Text = "…";
            btnPop.UseVisualStyleBackColor = true;
            btnPop.Click += new EventHandler(btnPop_Click);
            this.Controls.Add(btnPop);
        }

        void btnPop_Click(object sender, EventArgs e)
        {
            if (!popup.Visible)
                popup.Show(this);
            else
                popup.Close();

            this.SelectAll();
            this.Focus();
        }

        void DelayTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            DelayTimer.Stop();
            this.Invoke(new DelayOverHandler(UpdateData), null);
        }

        void list_ItemSelected(object sender, EventArgs e)
        {
            this.SelectedItem = this.list.GetSelectedItem();
        }

        private void CustFuzzyQueryBox_TextChanged(object sender, EventArgs e)
        {
            DelayTimer.Stop();
            DelayTimer.Start();
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            //return base.ProcessCmdKey(ref msg, keyData);
            //键盘向上
            if (keyData == Keys.Up)
            {
                list.SelectPreviousItem();
                return true;
            }
            //键盘向下
            else if (keyData == Keys.Down)
            {
                list.SelectNextItem();
                return true;
            }
            //回车
            else if (keyData == Keys.Enter)
            {
                this.SelectedItem = this.list.GetSelectedItem();
                return true;
            }
            //取消
            else if (keyData == Keys.Escape)
            {
                this.Text = "";
                this.SelectedItem = null;
                return true;
            }
            else
            {
                return base.ProcessCmdKey(ref msg, keyData);
            }
        }

        private void CustFuzzyQueryBox_Leave(object sender, EventArgs e)
        {
            popup.Close();
        }

        private void CustFuzzyQueryBox_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Delta < 0)
            {
                list.SelectNextItem();
            }
            else if (e.Delta > 0)
            {
                list.SelectPreviousItem();
            }
        }

        public delegate void DelayOverHandler();

        private void UpdateData()
        {
            string QueryInfo = this.Text;
            if (Text.Length > 0)
            {
                ////获取远程数据
                //WebRequestHelper wh = new WebRequestHelper();
                //IDictionary<string, string> dict = new Dictionary<string, string>();
                //dict.Add("QueryId", QueryId);
                //dict.Add("q", QueryInfo);
                //dict.Add("PageSize", "20");
                //string strJson = wh.DoGet("http://10.180.180.100:1983/api/easyQueryService/FuzzyQuery", dict);
                //IList<dynamic> data = strJson.JsonToObj<IList<dynamic>>();

                //list.DataSource = data;
                //popup.Show(this);

                if (QueryStringChangeEvent != null)
                {
                    QueryStringChangeEvent(this, new QueryStringChangeEventArgs(QueryInfo));
                    popup.Show(this);
                }
            }
            else
            {
                popup.Close();
            }
        }



        public object DataSource
        {
            get
            {
                return list.DataSource;
            }
            set
            {
                list.DataSource = value;
            }
        }



        const int IME_CMODE_FULLSHAPE = 0x8;
        const int IME_CHOTKEY_SHAPE_TOGGLE = 0x11;

        private void CustFuzzyQueryBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            //空格转换
            if (e.KeyChar == 12288)
            {
                e.KeyChar = Convert.ToChar(32);
            }
            //全角转半角
            else if (e.KeyChar >= 65280 && e.KeyChar <= 65375)
            {
                e.KeyChar -= Convert.ToChar(65248);
            }
        }

        //private void SetIme()
        //{
        //    IntPtr HIme = ImmGetContext(this.Handle);
        //    if (ImmGetOpenStatus(HIme))
        //    {
        //        int iMode = 0;
        //        int iSentence = 0;
        //        bool bSuccess = ImmGetConversionStatus(HIme, ref iMode, ref iSentence);
        //        if (bSuccess)
        //        {
        //            if ((iMode & IME_CMODE_FULLSHAPE) > 0)
        //            {
        //                ImmSimulateHotKey(this.Handle, IME_CHOTKEY_SHAPE_TOGGLE);
        //            }
        //        }
        //    }
        //}





        //private void CustFuzzyQueryBox_Enter(object sender, EventArgs e)
        //{
        //    SetIme();
        //}

        //private void CustFuzzyQueryBox_ImeModeChanged(object sender, EventArgs e)
        //{
        //    SetIme();
        //}

        //private void CustFuzzyQueryBox_VisibleChanged (object sender, EventArgs e)
        //{
        //    SetIme();
        //}
    }

    public delegate void AfterSelectorEventHandler(object sender, AfterSelectorEventArgs e);

    public class AfterSelectorEventArgs : EventArgs
    {
        private int _rowIndex;
        private int _columnIndex;
        private object _value;

        public int RowIndex
        {
            get { return _rowIndex; }
            set { _rowIndex = value; }
        }
        public int ColumnIndex
        {
            get { return _columnIndex; }
            set { _columnIndex = value; }
        }
        public object Value
        {
            get { return _value; }
            set { _value = value; }
        }

        public AfterSelectorEventArgs(int rowIndex, int columnIndex, object value)
            : base()
        {
            _rowIndex = rowIndex;
            _columnIndex = columnIndex;
            _value = value;
        }
    }

    public delegate void QueryStringChangeEventHandler(object sender, QueryStringChangeEventArgs e);

    public class QueryStringChangeEventArgs : EventArgs
    {
        private string _QueryString;
        public string QueryString
        {
            get { return this._QueryString; }
            set { this._QueryString = value; }
        }

        public QueryStringChangeEventArgs(string queryString)
            : base()
        {
            _QueryString = queryString;
        }
    }
}
